// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: implementation of CXFormsElementSwitch.
//   $Id$
#include "stdafx.h"

#include "SwitchUI.h"
#include "switch.h"
#include "parseSwitch.h"
#include "FP_Definitions.h"
#include "XFormsXFormsElement.h"
#include "case.h"
//////////////////////////////////////////////////////////////////////
// CXFormsElementSwitch Class
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CXFormsElementSwitch::CXFormsElementSwitch()
{

}

CXFormsElementSwitch::~CXFormsElementSwitch()
{

}

CImpl* CXFormsElementSwitch::CreateImpl()
{
	CImpl* pFormControl = (CImpl*) new CImplSwitch(this);

	return pFormControl;
}

CXFormsParse* CXFormsElementSwitch::CreateParse(CImpl* pImpl)
{
	CXFormsParse* pParse = new CXFormsParseSwitch((CImplSwitch*) pImpl);

	return pParse;
}

HRESULT CXFormsElementSwitch::put_value(BSTR/* sCaseId*/)
{
	return S_OK;
}

HRESULT CXFormsElementSwitch::render()
{
	CComPtr<IHTMLElement> pEl;
	HRESULT hr = GetMasterElement(&pEl);
	if(pEl)
	{
		CComBSTR sClassName;
		pEl->get_className(&sClassName);	
		CStringW csClassName(sClassName);
		csClassName.Replace(L"pc-notready",L"");
		sClassName.Empty();
		sClassName.Attach(csClassName.AllocSysString());
		pEl->put_className(sClassName);
	}
	return S_OK;
}

HRESULT CXFormsElementSwitch::put_XPathExpression(const BSTR bsXPath)
{
	return S_OK;
}



void CXFormsElementSwitch::RegisterFindBehaviourRefusal()
{
	//do nothing
#ifdef _DEBUG
	long l = 0;
#endif
}
void CXFormsElementSwitch::RegisterFindBehaviourAcceptance()
{
	//do nothing
#ifdef _DEBUG
	long l = 0;
#endif
}



HRESULT CXFormsElementSwitch::InitBehaviour(void)
{
	HRESULT hr =  __super::InitBehaviour();
	//Must be done here, as render is too late.
	// ElementReady for children is called 
	//	before parent.
	
	if(m_pXForms)
	{
		CComPtr<IHTMLElement> pEl;
		hr = GetMasterElement(&pEl);
		if(pEl)
		{
			CComBSTR sClassName;
			pEl->get_className(&sClassName);
			sClassName.Append(L" pc-notready");
			pEl->put_className(sClassName);
			pEl->setAttribute(CComBSTR(L"tabIndex"), CComVariant(-1, VT_I4), 1);
		}

	}
	return hr;
}

// Bug 465 - Because xf:case is now a behaviour the order in which they are parsed 
// can variry. So instead of taking the first case from the children list we need 
// to pick it up from the HTML Dom.
HRESULT CXFormsElementSwitch::getFirstCase(CImplCase ** pCase)
{
	HRESULT hr = S_FALSE;
	// Get the master element
	CComPtr<IHTMLElement> pEl;
	hr = GetMasterElement(&pEl);
	if(SUCCEEDED(hr) && pEl)
	{
		// Get the collection
		IDispatch * pDisp = 0;
		//TODO: check this - it may leack if FAILED(hr)
		hr = pEl->get_children(&pDisp);
		if(SUCCEEDED(hr) && pDisp) {
			CComQIPtr<IHTMLElementCollection> pColl = pDisp;
			pDisp->Release();
			pDisp = 0;

			long iLen, iCurr = 0;
			pColl->get_length(&iLen);

			CComVariant ZeroVar(0);
			CComVariant IndexVar(iCurr);
			// Loop throught the children until either the
			// end or a xf:case element.
			while(!*pCase && iCurr < iLen) {
				pColl->item(IndexVar,ZeroVar, &pDisp);

				CImpl * pImpl = 0;
				CComPtr<IElementBehavior> pBehavior;
				hr = CBinaryBehavior::GetNamedBehavior(g_bsAttrXFormsElementController, pDisp, &pBehavior);
				pDisp->Release();
				pDisp = 0;
			
				if(SUCCEEDED(hr) && pBehavior)
				{
					//Attempt to fetch Impl by casting to CXFormsElement

					CXFormsElement * pBehaviourAsXFormsElement = dynamic_cast<CXFormsElement *>(pBehavior.p);
					if(pBehaviourAsXFormsElement)
					{
						hr = pBehaviourAsXFormsElement->get_Impl(&pImpl);
					}
					else
						hr = m_pXForms->GetParentImpl(pBehavior,&pImpl);
				}
				
				*pCase = dynamic_cast<CImplCase *> (pImpl);
				iCurr ++;
				IndexVar = iCurr;
			}
		}
	}
	
	return hr;
}
